import re

from rest_framework import serializers
from rest_framework.exceptions import ValidationError

class RegexSerializer:
    def __init__(self, message):
        if message is not None:
            self.message = message

    def __call__(self, value):
        regex = re.compile(r'^[\w\d_]')
        if not regex.search(value):
            raise ValidationError(self.message)

class LoginSerializer(serializers.Serializer):
    """登录序列化器"""
    username = serializers.CharField(min_length=5, max_length=16, write_only=True, required=True,
                                     validators=[RegexSerializer('用户名只能包含字母数字和下划线')], help_text='用户名')
    password = serializers.CharField(min_length=5, max_length=16, write_only=True, required=True, help_text='密码')

    def validate_password(self, value):
        """验证密码是否合法"""
        regex = re.compile(r'^[\w\d_]')
        if not regex.search(value):
            raise ValidationError('密码只能包含字母数字和下划线')
        return value

class ResetPasswordSerializer(serializers.Serializer):
    """重置密码序列化器"""
    username = serializers.CharField(min_length=5, max_length=16, write_only=True, required=True,
                                     validators=[RegexSerializer('用户名只能包含字母数字和下划线')], help_text='用户名')
    password = serializers.CharField(min_length=5, max_length=16, write_only=True, required=True, help_text='密码')
    confirm = serializers.CharField(min_length=5, max_length=16, write_only=True, required=True, help_text='确认密码')

    def validate(self, attrs):
        password_1 = attrs.get('password')
        confirm_password = attrs.get('confirm')
        if password_1 != confirm_password:
            raise ValidationError('两次密码不一致')
        return attrs

    def validate_password(self, value):
        """验证密码是否合法"""
        regex = re.compile(r'^[\w\d_]')
        if not regex.search(value):
            raise ValidationError('密码只能包含字母数字和下划线')
        return value

    def validate_confirm(self, value):
        """确认密码是否正确"""
        regex = re.compile(r'^[\w\d_]')
        if not regex.search(value):
            raise ValidationError('确认密码只能包含字母数字和下划线')
        return value

    def save(self, **kwargs):
        self.instance.set_password(self.validated_data.get('password'))
        self.instance.save()
        return self.instance